home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
-
- Gnucleus - A node application for the Gnutella network
- Copyright (C) 2000 John Marshall
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For support, questions, comments, etc...
- E-Mail:
- swabby@c0re.net
-
- Address:
- 21 Cadogan Way
- Nashua, NH, USA 03062
-
- ********************************************************************************/
-
- // MainFrm.cpp : implementation of the CMainFrame class
- //
-
- #include "stdafx.h"
- #include "Gnucleus.h"
- #include "GnucleusDoc.h"
-
- #include "ViewConnect.h"
- #include "MainFrm.h"
-
- #include "GnuHash.h"
- #include "GnuControl.h"
-
- #define WM_ICON_NOTIFY WM_USER+10
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CMainFrame
-
- IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
-
- BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
- //{{AFX_MSG_MAP(CMainFrame)
- ON_WM_CREATE()
- ON_WM_TIMER()
- ON_COMMAND(ID_OPEN, OnOpenFromTray)
- ON_WM_SHOWWINDOW()
- ON_WM_NCACTIVATE()
- ON_WM_NCLBUTTONUP()
- ON_WM_NCLBUTTONDOWN()
- ON_WM_NCMOUSEMOVE()
- ON_WM_NCPAINT()
- ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
- ON_WM_PAINT()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- static UINT indicators[] =
- {
- ID_SEPARATOR, // status line indicator
- ID_INDICATOR_RECV,
- ID_INDICATOR_SEND
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // CMainFrame construction/destruction
-
- CMainFrame::CMainFrame()
- {
- Doc = (CGnucleusDoc *) ((CGnucleusApp *) AfxGetApp())->MasterDoc;
- m_bUseTrayIcon = TRUE;
- Strike = 0;
- InitializeTrayIcon();
- }
-
- CMainFrame::~CMainFrame()
- {
- RemoveIcon();
- m_wndTrayIcon.DestroyWindow();
- }
-
- int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- if (!m_wndToolBar.CreateEx(this) ||
- !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
- {
- TRACE0("Failed to create toolbar\n");
- return -1; // fail to create
- }
- if (!m_wndDlgBar.Create(this, IDR_MAINFRAME,
- CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR))
- {
- TRACE0("Failed to create dialogbar\n");
- return -1; // fail to create
- }
- else
- {
- CComboBox* cbptr = ((CComboBox *) m_wndDlgBar.GetDlgItem(IDC_COMBO_SPEED));
-
- cbptr->InsertString(0, "T3 (or Greater)");
- cbptr->InsertString(0, "T1");
- cbptr->InsertString(0, "DSL");
- cbptr->InsertString(0, "Cable");
- cbptr->InsertString(0, "ISDN-128K");
- cbptr->InsertString(0, "ISDN-56K");
- cbptr->InsertString(0, "56K Modem");
- cbptr->InsertString(0, "33.6 Modem");
- cbptr->InsertString(0, "28.8 Modem");
- cbptr->InsertString(0, "14.4 Modem");
- cbptr->InsertString(0, "");
- }
-
- if (!m_wndReBar.Create(this) ||
- !m_wndReBar.AddBar(&m_wndToolBar) ||
- !m_wndReBar.AddBar(&m_wndDlgBar))
- {
- TRACE0("Failed to create rebar\n");
- return -1; // fail to create
- }
-
- if (!m_wndStatusBar.Create(this) ||
- !m_wndStatusBar.SetIndicators(indicators,
- sizeof(indicators)/sizeof(UINT)))
- {
- TRACE0("Failed to create status bar\n");
- return -1; // fail to create
- }
- else
- {
- m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_RECV, SBPS_NORMAL, 140);
- m_wndStatusBar.SetPaneInfo(2, ID_INDICATOR_SEND, SBPS_NORMAL, 125);
- }
-
- if (!CreateTrayIcon(this, WM_ICON_NOTIFY, _T("Gnucleus"), AfxGetApp()->LoadIcon(IDR_MAINFRAME),
- IDR_TRAY))
- {
- TRACE0("Failed to create system tray icon.\n");
- return -1; // fail to create
- }
- else
- {
- HideIcon();
- if (m_bOwnerCreated)
- {
- ShowTaskBarButton(TRUE);
- }
- }
-
- // TODO: Remove this if you don't want tool tips
- m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
- CBRS_TOOLTIPS | CBRS_FLYBY);
-
- UpdateTimer = SetTimer(1, 1000, 0);
-
- return 0;
- }
-
- void CMainFrame::InitializeTrayIcon()
- {
- memset(&m_tnd, 0, sizeof(m_tnd));
- m_bEnabled = FALSE;
- m_bHidden = FALSE;
- m_hSavedIcon = NULL;
- m_DefaultMenuItemID = 0;
- m_DefaultMenuItemByPos = TRUE;
- }
-
- BOOL CMainFrame::CreateTrayIcon(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip,
- HICON icon, UINT uID)
- {
- // this is only for Windows 95 (or higher)
- VERIFY(m_bEnabled = ( GetVersion() & 0xff ) >= 4);
- if (!m_bEnabled) return FALSE;
-
- // Make sure Notification window is valid (not needed - CJM)
- // VERIFY(m_bEnabled = (pParent && ::IsWindow(pParent->GetSafeHwnd())));
- // if (!m_bEnabled) return FALSE;
-
- // Make sure we avoid conflict with other messages
- ASSERT(uCallbackMessage >= WM_USER);
-
- // Tray only supports tooltip text up to 64 characters
- ASSERT(_tcslen(szToolTip) <= 64);
-
- // Create an invisible window
- m_wndTrayIcon.CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, 0,0,10,10, NULL, 0);
-
- // load up the NOTIFYICONDATA structure
- m_tnd.cbSize = sizeof(NOTIFYICONDATA);
- m_tnd.hWnd = pParent->GetSafeHwnd()? pParent->GetSafeHwnd() : m_wndTrayIcon.GetSafeHwnd();
- m_tnd.uID = uID;
- m_tnd.hIcon = icon;
- m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
- m_tnd.uCallbackMessage = uCallbackMessage;
- _tcscpy(m_tnd.szTip, szToolTip);
-
- // Set the tray icon
- VERIFY(m_bEnabled = Shell_NotifyIcon(NIM_ADD, &m_tnd));
- return m_bEnabled;
- }
-
- BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
- {
- if (!CMDIFrameWnd::PreCreateWindow(cs)) return FALSE;
- if (!m_bOwnerCreated) // "dialog-is-created" flag
- {
- // m_MainFrameOwner - CDialog object mapped to the resource dialog template
- m_bOwnerCreated = m_MainFrameOwner.Create(IDD_OWNERFRAME);
- if (m_bOwnerCreated) m_MainFrameOwner.ShowWindow(SW_HIDE);
- };
-
- // set the dialog as a parent of CMainFrame window
- if (m_bOwnerCreated)
- {
- cs.hwndParent = m_MainFrameOwner.GetSafeHwnd();
- }
-
- return TRUE;
- }
-
- BOOL CMainFrame::ShowTaskBarButton(BOOL bVisible)
- {
- if (!m_bOwnerCreated) return FALSE;
-
- // ShowWindow(SW_HIDE); // seems to cause various problems,
- // ranging from flashing windows to the title bar disappearing
-
- if (bVisible)
- ModifyStyleEx(0, WS_EX_APPWINDOW);
- else
- ModifyStyleEx(WS_EX_APPWINDOW, 0);
-
- // ShowWindow(SW_SHOW);
-
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMainFrame diagnostics
-
- #ifdef _DEBUG
- void CMainFrame::AssertValid() const
- {
- CMDIFrameWnd::AssertValid();
- }
-
- void CMainFrame::Dump(CDumpContext& dc) const
- {
- CMDIFrameWnd::Dump(dc);
- }
-
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CMainFrame message handlers
-
- CDialogBar* CMainFrame::GetDialogBar()
- {
- return &m_wndDlgBar;
- }
-
- void CMainFrame::OnTimer(UINT nIDEvent)
- {
-
- if(nIDEvent == UpdateTimer)
- {
- int decimal, sign;
- float BytesIn = (float) Doc->GnuComm->BytesIn,
- BytesOut = (float) Doc->GnuComm->BytesOut,
- ByteLimit = (float) Doc->m_LimitTotal,
- Kilo = 1024;
-
- // call thread flow control OnTimer only once a second
- Doc->GnuComm->OnTimer();
-
-
- // Reset
- Doc->GnuComm->BytesIn = 0;
- Doc->GnuComm->BytesOut = 0;
-
- // The the estimated speed for gnucleus
- Doc->m_EstSpeed = GetEstSpeed(BytesIn * 8 / 1024);
-
- // Receive status bar update
- float Old_RecvSpeed = atof(m_wndStatusBar.GetPaneText(1));
- // CString Speed = _fcvt( ((BytesIn / Kilo) + Old_RecvSpeed) / 2, 2, &decimal, &sign );
- CString Speed = _fcvt( Doc->GnuComm->m_dwBytesPerSecIn / Kilo, 2, &decimal, &sign );
- Speed.Insert(decimal, ".");
-
- CString Title = "Receive rate: ";
- Title += Speed;
- Title += " KB/s";
- m_wndStatusBar.SetPaneText(1, Title);
-
- // Send status bar update
- float Old_SendSpeed = atof(m_wndStatusBar.GetPaneText(2));
- // Speed = _fcvt( ((BytesOut / Kilo) + Old_SendSpeed) / 2, 2, &decimal, &sign );
- Speed = _fcvt( Doc->GnuComm->m_dwBytesPerSecOut / Kilo, 2, &decimal, &sign );
- Speed.Insert(decimal, ".");
-
- Title = "Send rate: ";
- Title += Speed;
- Title += " KB/s";
- m_wndStatusBar.SetPaneText(2, Title);
-
- /*
- // Drop if limit hit
- float AverageSpeed = (((BytesOut + BytesIn) / Kilo) + (Old_RecvSpeed + Old_SendSpeed)) / 2;
-
- if(ByteLimit != 0)
- if(ByteLimit < AverageSpeed)
- if(AverageSpeed - ByteLimit > 1)
- Strike++;
- else
- Strike = 0;
- */
-
- // If limit is hit 3 times in a row, drop the connection
- if(Strike > 10)
- {
- Strike = 0;
-
- Doc->m_ConnectNum--;
-
- if( Doc->m_ConnectNum == 0)
- AfxMessageBox("Not enough bandwidth to support Gnucleus.");
-
- ((CViewConnect * ) ((CGnucleusApp *) AfxGetApp())->ConnectFrame->GetActiveView())->RemoveFirstNode();
- }
- }
-
- CMDIFrameWnd::OnTimer(nIDEvent);
- }
-
- DWORD CMainFrame::GetEstSpeed(DWORD CurrentSpeed)
- {
- if(CurrentSpeed <= Doc->m_EstSpeed)
- return Doc->m_EstSpeed;
- else
- {
- if(CurrentSpeed > 45000)
- return 45000;
- if(CurrentSpeed > 1500)
- return 1500;
- if(CurrentSpeed > 768)
- return 768;
- if(CurrentSpeed > 384)
- return 384;
- if(CurrentSpeed > 128)
- return 128;
- if(CurrentSpeed > 56)
- return 56;
- if(CurrentSpeed > 53)
- return 53;
- if(CurrentSpeed > 29)
- return 29;
- if(CurrentSpeed > 14)
- return 14;
- }
-
- return 0;
- }
-
- BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
- {
- // Entering return in they keyword box submits a search
- if(wParam == 1 && lParam == 0)
- {
- ((CGnucleusApp *) AfxGetApp())->OnButtonSearch();
- }
-
- return CMDIFrameWnd::OnCommand(wParam, lParam);
- }
-
- void CMainFrame::OnOpenFromTray()
- {
- this->ShowWindow(SW_RESTORE);
- HideIcon();
- ShowTaskBarButton(TRUE);
- }
-
- void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus)
- {
- CMDIFrameWnd::OnShowWindow(bShow, nStatus);
-
- // I don't know what the following code needs to be here for,
- // but it makes a massive headache on Win 9x (stack overflow).
- /*
- if (bShow)
- {
- HideIcon();
- ShowTaskBarButton(TRUE);
- }
- */
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Tray Icon manipulation
-
- void CMainFrame::MoveToRight()
- {
- HideIcon();
- ShowIcon();
- }
-
- void CMainFrame::RemoveIcon()
- {
- if (!m_bEnabled) return;
-
- m_tnd.uFlags = 0;
- Shell_NotifyIcon(NIM_DELETE, &m_tnd);
- m_bEnabled = FALSE;
- }
-
- void CMainFrame::HideIcon()
- {
- if (m_bEnabled && !m_bHidden) {
- m_tnd.uFlags = NIF_ICON;
- Shell_NotifyIcon (NIM_DELETE, &m_tnd);
- m_bHidden = TRUE;
- }
- }
-
- void CMainFrame::ShowIcon()
- {
- if (m_bEnabled && m_bHidden) {
- m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
- Shell_NotifyIcon(NIM_ADD, &m_tnd);
- m_bHidden = FALSE;
- }
- }
-
- BOOL CMainFrame::SetIcon(HICON hIcon)
- {
- if (!m_bEnabled) return FALSE;
-
- m_tnd.uFlags = NIF_ICON;
- m_tnd.hIcon = hIcon;
-
- return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
- }
-
- BOOL CMainFrame::SetIcon(LPCTSTR lpszIconName)
- {
- HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);
-
- return SetIcon(hIcon);
- }
-
- BOOL CMainFrame::SetIcon(UINT nIDResource)
- {
- HICON hIcon = AfxGetApp()->LoadIcon(nIDResource);
-
- return SetIcon(hIcon);
- }
-
- BOOL CMainFrame::SetStandardIcon(LPCTSTR lpIconName)
- {
- HICON hIcon = LoadIcon(NULL, lpIconName);
-
- return SetIcon(hIcon);
- }
-
- BOOL CMainFrame::SetStandardIcon(UINT nIDResource)
- {
- HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource));
-
- return SetIcon(hIcon);
- }
-
- HICON CMainFrame::GetIcon() const
- {
- return (m_bEnabled)? m_tnd.hIcon : NULL;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Tray Icon tooltip text manipulation
-
- BOOL CMainFrame::SetTooltipText(LPCTSTR pszTip)
- {
- if (!m_bEnabled) return FALSE;
-
- m_tnd.uFlags = NIF_TIP;
- _tcscpy(m_tnd.szTip, pszTip);
-
- return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
- }
-
- BOOL CMainFrame::SetTooltipText(UINT nID)
- {
- CString strText;
- VERIFY(strText.LoadString(nID));
-
- return SetTooltipText(strText);
- }
-
- CString CMainFrame::GetTooltipText() const
- {
- CString strText;
- if (m_bEnabled)
- strText = m_tnd.szTip;
-
- return strText;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Tray Icon notification window stuff
-
- BOOL CMainFrame::SetNotificationWnd(CWnd* pWnd)
- {
- if (!m_bEnabled) return FALSE;
-
- // Make sure Notification window is valid
- ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd()));
-
- m_tnd.hWnd = pWnd->GetSafeHwnd();
- m_tnd.uFlags = 0;
-
- return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
- }
-
- CWnd* CMainFrame::GetNotificationWnd() const
- {
- return CWnd::FromHandle(m_tnd.hWnd);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Tray Icon menu manipulation
-
- BOOL CMainFrame::SetMenuDefaultItem(UINT uItem, BOOL bByPos)
- {
- if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos == bByPos))
- return TRUE;
-
- m_DefaultMenuItemID = uItem;
- m_DefaultMenuItemByPos = bByPos;
-
- CMenu menu, *pSubMenu;
-
- if (!menu.LoadMenu(m_tnd.uID)) return FALSE;
- if (!(pSubMenu = menu.GetSubMenu(0))) return FALSE;
-
- ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos);
-
- return TRUE;
- }
-
- void CMainFrame::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos)
- {
- uItem = m_DefaultMenuItemID;
- bByPos = m_DefaultMenuItemByPos;
- }
-
- LRESULT CMainFrame::OnTrayNotification(UINT wParam, LONG lParam)
- {
- //Return quickly if its not for this tray icon
- if (wParam != m_tnd.uID)
- return 0L;
-
- CMenu menu, *pSubMenu;
- CWnd* pTarget = AfxGetMainWnd();
-
- // Clicking with right button brings up a context menu
- if (LOWORD(lParam) == WM_RBUTTONUP)
- {
- if (!menu.LoadMenu(m_tnd.uID)) return 0;
- if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
-
- // Make chosen menu item the default (bold font)
- ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos);
-
- // Display and track the popup menu
- CPoint pos;
- GetCursorPos(&pos);
-
- pTarget->SetForegroundWindow();
- ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0,
- pTarget->GetSafeHwnd(), NULL);
-
- // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
- pTarget->PostMessage(WM_NULL, 0, 0);
-
- menu.DestroyMenu();
- }
- else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
- {
- // double click received, the default action is to execute default menu item
- pTarget->SetForegroundWindow();
-
- UINT uItem;
- if (m_DefaultMenuItemByPos)
- {
- if (!menu.LoadMenu(m_tnd.uID)) return 0;
- if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
- uItem = pSubMenu->GetMenuItemID(m_DefaultMenuItemID);
- }
- else
- uItem = m_DefaultMenuItemID;
-
- pTarget->SendMessage(WM_COMMAND, uItem, 0);
-
- menu.DestroyMenu();
- }
-
- return 1;
- }
-
- LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- {
- if (message == m_tnd.uCallbackMessage)
- return OnTrayNotification(wParam, lParam);
-
- return CWnd::WindowProc(message, wParam, lParam);
- }
-
-
-
- BOOL CMainFrame::OnNcActivate(BOOL bActive)
- {
- // Add iconize button to caption
- DrawButtons( GetSafeHwnd() );
-
- return CMDIFrameWnd::OnNcActivate(bActive);
- }
-
-
- void CMainFrame::OnNcLButtonUp(UINT nHitTest, CPoint point)
- {
- HDC hDc ;
- RECT rPos ;
- RECT rWin ;
-
- // Redraw caption buttons
- if ( ( hDc = ::GetWindowDC( GetSafeHwnd() ) ) != NULL )
- {
- // Convert mouse postion relative to caption rectangle
- GetWindowRect(&rWin);
-
- // Calculate rectangle position of iconize button
- CalcCaptionRect( GetSafeHwnd(), rPos );
- rPos.top += 2;
- rPos.bottom -= 2;
- rPos.right -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) );
- rPos.left = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );
-
- point.x = point.x - rWin.left;
- point.y = point.y - rWin.top;
-
- // Check if mouse position is in rectangle
- if ( PtInRect( &rPos, point) )
- {
- SendMessage( WM_SYSCOMMAND, SC_MINIMIZE, 0 );
- ShowWindow( SW_HIDE );
- ShowIcon();
- ShowTaskBarButton(FALSE);
- }
- else
- CMDIFrameWnd::OnNcLButtonUp(nHitTest, point);
-
- DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );
- DrawIconize( hDc, rPos.left, rPos.top, 0 );
- m_LBtnDown = FALSE;
- DeleteObject( hDc );
- }
- }
-
- void CMainFrame::OnNcLButtonDown(UINT nHitTest, CPoint point)
- {
- HDC hDc ;
- RECT rPos ;
- RECT rWin ;
-
- // Redraw caption buttons
- if ( ( hDc = ::GetWindowDC( GetSafeHwnd()) ) != NULL )
- {
- // Convert mouse postion relative to caption rectangle
- ::GetWindowRect( GetSafeHwnd(), &rWin );
-
- // Calculate rectangle position of iconize button
- CalcCaptionRect( GetSafeHwnd(), rPos );
- rPos.top += 2;
- rPos.bottom -= 2;
- rPos.right -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) );
- rPos.left = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );
-
- point.x = point.x - rWin.left;
- point.y = point.y - rWin.top;
-
- // Check if mouse position is in rectangle
- if ( PtInRect( &rPos, point) )
- {
- m_LBtnDown = TRUE;
- DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED );
- DrawIconize( hDc, rPos.left, rPos.top, 1 );
- }
- else
- CMDIFrameWnd::OnNcLButtonDown(nHitTest, point) ;
-
- DeleteObject( hDc );
- }
- }
-
- void CMainFrame::OnNcMouseMove(UINT nHitTest, CPoint point)
- {
- HDC hDc ;
- RECT rPos ;
- RECT rWin ;
-
- // Redraw caption buttons
- if ( ( hDc = ::GetWindowDC( GetSafeHwnd() ) ) != NULL )
- {
- // Convert mouse postion relative to caption rectangle
- ::GetWindowRect( GetSafeHwnd(), &rWin );
-
- // Calculate rectangle position of iconize button
- CalcCaptionRect( GetSafeHwnd(), rPos );
- rPos.top += 2;
- rPos.bottom -= 2;
- rPos.right -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) );
- rPos.left = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );
-
- point.x = point.x - rWin.left;
- point.y = point.y - rWin.top;
-
- // Check if mouse position is in rectangle
- if ( PtInRect( &rPos, point) )
- {
- DrawFrameControl( hDc, &rPos, DFC_BUTTON, ( m_LBtnDown ) ? DFCS_BUTTONPUSH | DFCS_PUSHED : DFCS_BUTTONPUSH );
- DrawIconize( hDc, rPos.left, rPos.top, ( m_LBtnDown ) ? 1 : 0 );
- }
- else
- {
- m_LBtnDown = FALSE;
- DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );
- DrawIconize( hDc, rPos.left, rPos.top, 0 );
- CMDIFrameWnd::OnNcMouseMove(nHitTest, point) ;
- }
-
- DeleteObject( hDc );
- }
- }
-
- void CMainFrame::OnNcPaint()
- {
- CMDIFrameWnd::OnNcPaint();
-
- // Add iconize button to caption
- DrawButtons( GetSafeHwnd() );
- }
-
-
- void CMainFrame::CalcCaptionRect( HWND hWnd, RECT& Rect )
- {
- DWORD dStyle ;
- SIZE sFrame ;
- int Icon ;
-
- // Get frame size of window
- dStyle = GetWindowLong( hWnd, GWL_STYLE );
- sFrame.cx = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME );
- sFrame.cy = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME );
-
- // Get width of icon/button in caption
- Icon = GetSystemMetrics( SM_CXSIZE );
-
- // Calculate rectangle dimensions
- ::GetWindowRect( hWnd, &Rect );
- Rect.bottom -= Rect.top;
- Rect.right -= Rect.left;
- Rect.top = 0;
- Rect.left = 0;
-
- Rect.left += sFrame.cx;
- Rect.right -= sFrame.cx;
- Rect.top += sFrame.cy;
- Rect.bottom = Rect.top + GetSystemMetrics( SM_CYCAPTION )
- - GetSystemMetrics( SM_CYBORDER );
- }
-
-
-
- void CMainFrame::DrawIconize( HDC hDc, int x, int y, int off )
- {
- //
- // TODO:
- // This should be done flikker free by means
- // of a memory DC
- //
-
- HPEN Pen, oldPen;
- HBRUSH Brush, oldBrush;
-
- int cxBtn = GetSystemMetrics( SM_CXSIZE ) - 5;
- int cyBtn = GetSystemMetrics( SM_CYSIZE ) - 5;
-
- Pen = CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) );
- oldPen = (HPEN) SelectObject( hDc, Pen );
-
- Brush = CreateSolidBrush( RGB(0,0,0) );
- oldBrush = (HBRUSH) SelectObject(hDc, Brush);
-
- // Use a filled circle in the bottom right corner to signify minimize to icon.
- Ellipse(hDc, x + 1 + cxBtn*1/2 + off, y + 1 + cyBtn*1/2,
- x + 1 + cxBtn*5/6, y + 1 + cyBtn*3/4);
-
- SelectObject( hDc, oldPen );
- DeleteObject( Pen );
-
- SelectObject( hDc, oldBrush );
- DeleteObject( Brush );
- }
-
- void CMainFrame::DrawButtons( HWND hWnd )
- {
- HDC hDc ;
- RECT rCap ;
- DWORD dStyle ;
- DWORD dExStyle ;
- int cxBtn ;
- int cyBtn ;
- RECT rPos ;
-
- // Get window device context
- if ( ( hDc = ::GetWindowDC( hWnd ) ) != NULL )
- {
- // Get caption coordinates
- CalcCaptionRect( hWnd, rCap );
-
- // Get window style
- dStyle = GetWindowLong( hWnd, GWL_STYLE );
- dExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
-
- // Check if we have a caption
- if ( ( dStyle & WS_CAPTION ) == WS_CAPTION )
- {
- // Get button dimensions
- cxBtn = GetSystemMetrics( SM_CXSIZE );
- cyBtn = GetSystemMetrics( SM_CYSIZE );
-
- // Calc position and draw close button
- rPos.top = rCap.top + 2;
- rPos.bottom = rCap.bottom - 2;
- rPos.right = rCap.right - 2;
- rPos.left = rCap.right - 2 - ( cxBtn - 2);
- DrawFrameControl( hDc, &rPos, DFC_CAPTION, DFCS_CAPTIONCLOSE );
-
- // Calc position and draw maximize<->restore/help button
- if ( ( dStyle & WS_MAXIMIZEBOX ) == WS_MAXIMIZEBOX )
- {
- rPos.right -= cxBtn;
- rPos.left -= cxBtn;
- DrawFrameControl( hDc, &rPos, DFC_CAPTION, ::IsZoomed( hWnd ) ? DFCS_CAPTIONRESTORE
- : DFCS_CAPTIONMAX );
- }
- else if ( ( dExStyle & WS_EX_CONTEXTHELP ) == WS_EX_CONTEXTHELP )
- {
- rPos.right -= cxBtn;
- rPos.left -= cxBtn;
- DrawFrameControl( hDc, &rPos, DFC_CAPTION, DFCS_CAPTIONHELP );
- }
-
- // Calc position and draw minimize and iconize button
- if ( ( dStyle & WS_MINIMIZEBOX ) == WS_MINIMIZEBOX )
- {
- // Minimize button
- rPos.right -= ( cxBtn - 2 );
- rPos.left -= ( cxBtn - 2 );
- DrawFrameControl( hDc, &rPos, DFC_CAPTION, DFCS_CAPTIONMIN );
-
- // Iconize button
- rPos.right -= ( cxBtn - 2 ) + 2;
- rPos.left -= ( cxBtn - 2 ) + 2;
- DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );
-
- // Draw a btnface
- DrawIconize( hDc, rPos.left, rPos.top, 0 );
- }
- }
-
- // Release device context
- ::ReleaseDC( hWnd, hDc );
- }
- }
-
- void CMainFrame::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
-
- // Add iconize button to caption
- DrawButtons( GetSafeHwnd() );
- }
-